"""
Tank base class and related functionality
"""
import pygame
import math
from typing import Tuple, Optional
from utils.constants import Direction, TankType
from utils.config import TANK_SPEED, WHITE, RED, BLUE, GREEN


class Tank:
    """Base tank class"""
    
    def __init__(self, x: int, y: int, tank_type: str = TankType.PLAYER):
        """
        Initialize tank
        
        Args:
            x: X coordinate
            y: Y coordinate
            tank_type: Type of tank
        """
        self.x = x
        self.y = y
        self.tank_type = tank_type
        
        # Tank properties
        self.width = 32
        self.height = 32
        self.speed = TANK_SPEED
        self.direction = Direction.UP
        self.lives = 1
        
        # Movement
        self.moving = False
        self.move_timer = 0
        self.move_delay = 100  # milliseconds
        
        # Visual properties
        self.color = self._get_tank_color()
        self.rect = pygame.Rect(x, y, self.width, self.height)
        
        # Animation
        self.animation_frame = 0
        self.animation_speed = 0.2
        
    def _get_tank_color(self) -> Tuple[int, int, int]:
        """Get tank color based on type"""
        color_map = {
            TankType.PLAYER: GREEN,
            TankType.ENEMY_BASIC: RED,
            TankType.ENEMY_FAST: BLUE,
            TankType.ENEMY_HEAVY: (128, 0, 128)  # Purple
        }
        return color_map.get(self.tank_type, WHITE)
    
    def move(self, direction: int) -> bool:
        """
        Move tank in specified direction
        
        Args:
            direction: Direction to move (Direction enum)
            
        Returns:
            True if movement was successful
        """
        self.direction = direction
        self.moving = True
        
        # Calculate new position
        dx, dy = self._get_direction_vector(direction)
        new_x = self.x + dx * self.speed
        new_y = self.y + dy * self.speed
        
        # Update position
        self.x = new_x
        self.y = new_y
        self.rect.x = int(self.x)
        self.rect.y = int(self.y)
        
        return True
    
    def _get_direction_vector(self, direction: int) -> Tuple[int, int]:
        """Get movement vector for direction"""
        vectors = {
            Direction.UP: (0, -1),
            Direction.DOWN: (0, 1),
            Direction.LEFT: (-1, 0),
            Direction.RIGHT: (1, 0)
        }
        return vectors.get(direction, (0, 0))
    
    def rotate(self, direction: int):
        """
        Rotate tank to face direction
        
        Args:
            direction: Direction to face (Direction enum)
        """
        self.direction = direction
    
    def get_front_position(self) -> Tuple[int, int]:
        """Get position of tank front (for bullet spawning)"""
        dx, dy = self._get_direction_vector(self.direction)
        front_x = self.x + self.width // 2 + dx * (self.width // 2 + 5)
        front_y = self.y + self.height // 2 + dy * (self.height // 2 + 5)
        return int(front_x), int(front_y)
    
    def take_damage(self, damage: int = 1) -> bool:
        """
        Take damage and return True if tank is destroyed
        
        Args:
            damage: Amount of damage to take
            
        Returns:
            True if tank is destroyed
        """
        self.lives -= damage
        if self.lives <= 0:
            self.lives = 0
            self._on_destroyed()
        return self.lives <= 0
    
    def _on_destroyed(self):
        """Called when tank is destroyed"""
        # This can be overridden by subclasses for specific behavior
        pass
    
    def heal(self, amount: int = 1) -> bool:
        """
        Heal tank by specified amount
        
        Args:
            amount: Amount of health to restore
            
        Returns:
            True if healing was successful
        """
        if self.lives > 0:  # Can't heal dead tank
            self.lives += amount
            return True
        return False
    
    def get_max_lives(self) -> int:
        """Get maximum lives for this tank type"""
        if self.tank_type == TankType.PLAYER:
            return 3
        else:
            return 1
    
    def get_health_percentage(self) -> float:
        """Get health as percentage (0.0 to 1.0)"""
        max_lives = self.get_max_lives()
        return self.lives / max_lives if max_lives > 0 else 0.0
    
    def is_alive(self) -> bool:
        """Check if tank is alive"""
        return self.lives > 0
    
    def update(self, dt: float):
        """
        Update tank state
        
        Args:
            dt: Delta time in seconds
        """
        # Update animation
        self.animation_frame += self.animation_speed * dt * 60
        if self.animation_frame >= 4:
            self.animation_frame = 0
        
        # Update movement timer
        if self.moving:
            self.move_timer += dt * 1000
            if self.move_timer >= self.move_delay:
                self.move_timer = 0
                self.moving = False
    
    def render(self, screen: pygame.Surface):
        """
        Render tank on screen
        
        Args:
            screen: Pygame surface to render on
        """
        if not self.is_alive():
            return
        
        # Draw tank body
        pygame.draw.rect(screen, self.color, self.rect)
        
        # Draw tank barrel based on direction
        barrel_length = 15
        center_x = self.x + self.width // 2
        center_y = self.y + self.height // 2
        
        # Calculate barrel end position
        dx, dy = self._get_direction_vector(self.direction)
        barrel_end_x = center_x + dx * barrel_length
        barrel_end_y = center_y + dy * barrel_length
        
        # Draw barrel
        pygame.draw.line(screen, self.color, 
                        (center_x, center_y), 
                        (barrel_end_x, barrel_end_y), 3)
        
        # Draw tank details
        self._draw_tank_details(screen)
    
    def _draw_tank_details(self, screen: pygame.Surface):
        """Draw additional tank details"""
        # Draw tank tracks
        track_color = (self.color[0] // 2, self.color[1] // 2, self.color[2] // 2)
        
        # Top track
        pygame.draw.rect(screen, track_color, 
                        (self.x + 2, self.y + 2, self.width - 4, 4))
        
        # Bottom track
        pygame.draw.rect(screen, track_color, 
                        (self.x + 2, self.y + self.height - 6, self.width - 4, 4))
        
        # Draw tank number or symbol
        font = pygame.font.Font(None, 16)
        if self.tank_type == TankType.PLAYER:
            text = font.render("P", True, WHITE)
        else:
            text = font.render("E", True, WHITE)
        
        text_rect = text.get_rect(center=(self.x + self.width // 2, 
                                         self.y + self.height // 2))
        screen.blit(text, text_rect)
    
    def get_collision_rect(self) -> pygame.Rect:
        """Get collision rectangle for tank"""
        return self.rect.copy()
    
    def set_position(self, x: int, y: int):
        """Set tank position"""
        self.x = x
        self.y = y
        self.rect.x = x
        self.rect.y = y
